package com.binguo.thirdPay.saoBeiPay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.paymodel.YilingPayResult;
import com.binguo.thirdPay.MD5Util;
import com.binguo.thirdPay.ruijingPay.RuiJingShopService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author yuritian
 * @Title: SaoBeiPayService
 * @ProjectName binguoDevelop
 * @Description: TODO
 * @date 2020/6/910:12
 */
@Service
public class SaoBeiPayService {

    private static Logger logger = LoggerFactory.getLogger(SaoBeiPayService.class);

    /**测试网址*/
//    private final String URL = "http://test.lcsw.cn:8045/lcsw";

    /**正式网址*/
    private final String URL = "https://pay.lcsw.cn/lcsw";

    /**测试token*/
//    private final String TOKEN = "73f2ed2f61ae459bae68dea6dbb4c581";

    /**正式token*/
    private final String TOKEN = "807e5b1b3ee54b509121d03f765b19f3";

    private final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");

    public static void main(String[] args) {
        SaoBeiPayService saoBeiPayService = new SaoBeiPayService();
        //saoBeiPayService.qrcodePay("852100210001211","11809980","YunpengTest0001","289338728360857074","1");
        //saoBeiPayService.queryOrder("819605541000001","30759322","","YunpengTest001","20200611103522");
        //saoBeiPayService.refundOrder("819605541000001","30759322","307593220022120060916282300005","1");
        //saoBeiPayService.cancelOrder("819605541000001","30759322",null,"1","1");
    }

    /**
     * @Author: yujing
     * @Description: 扫呗二维码支付
     * @param merchantNo 商户号
	 * @param terminalId 终端号
	 * @param terminalTrace 商户系统的订单号
	 * @param authNo 付款码
	 * @param totalFee 金额，单位分
     * @DateTime: 2020/6/9 17:36
     * @Return void
     */
    public JSONObject qrcodePay(String merchantNo,
                                String terminalId,
                                String terminalTrace,
                                String authNo,
                                String totalFee,
                                Date date){
        JSONObject qrcodePayResult = new JSONObject();

        StringBuilder signStr = new StringBuilder();

        LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();


        String terminalTime = dateTimeFormat.format(date);

        map.put("pay_ver","100");
        map.put("pay_type","000");
        map.put("service_id","010");
        map.put("merchant_no",merchantNo);
        map.put("terminal_id",terminalId);
        map.put("terminal_trace",terminalTrace);
        map.put("terminal_time",terminalTime);
        map.put("auth_no",authNo);
        map.put("total_fee",totalFee);

        for(Map.Entry<String, String> entry : map.entrySet()) {
            signStr.append(entry.getKey() + "=" + entry.getValue() + "&");
        }

        signStr.append("access_token=").append(TOKEN);
        System.out.println(signStr);
        String keySign = MD5Util.MD5Lower32(signStr.toString());
        map.put("key_sign",keySign);

        String postJson = JSON.toJSONString(map);
        JSONObject saoBeiResult = getPostRessultJson("/pay/100/barcodepay",postJson);
        String returnCode = saoBeiResult.getString("return_code");
        if (!returnCode.equals("01")){
            logger.info("服务器与扫呗通信失败");
            throw new ServiceException("支付失败");
        }
        qrcodePayResult.put("terminalTrace",terminalTrace);
        qrcodePayResult.put("terminalTime",terminalTime);
        qrcodePayResult.put("payType",saoBeiResult.getString("pay_type"));
        qrcodePayResult.put("outTradeNo",saoBeiResult.getString("out_trade_no"));
        String resultCode = saoBeiResult.getString("result_code");
        if (resultCode.equals("01")){
            return qrcodePayResult;
        }else if (resultCode.equals("03")){
            String outTradeNo = saoBeiResult.getString("out_trade_no");
            if (StringUtils.isEmpty(outTradeNo)){
                outTradeNo = new String();
            }
            int count = 0;
            boolean doWhile = false;
            while(!doWhile) {
                try {
                    //设置暂停的时间 5 秒
                    Thread.sleep(5 * 1000);
                    count ++ ;
                    logger.info("扫呗订单查询支付状态请求第" + count + "次");
                    JSONObject queryResult = queryOrder(merchantNo,terminalId,outTradeNo,terminalTrace,terminalTime);
                    String queryResultCode = queryResult.getString("result_code");
                    if (queryResultCode.equals("01")){
                        return qrcodePayResult;
                    }else if (queryResultCode.equals("02")){
                        throw new ServiceException("支付失败");
                    }
                    if (count == 6){
                        cancelOrder(merchantNo,terminalId,outTradeNo,terminalTrace,terminalTime);
                        throw new ServiceException("支付超时");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }else {
            logger.info("扫呗支付失败");
            throw new ServiceException("支付失败");
        }
        throw new ServiceException("支付失败");
    }

    /**
     * @Author: yujing
     * @Description: 查询订单
     * @param merchantNo 商户号
	 * @param terminalId 终端号
	 * @param outTradeNo qrcodePay获取的得到的outTradeNo
     * @DateTime: 2020/6/9 17:38
     * @Return void
     */
    public JSONObject queryOrder(String merchantNo,
                                 String terminalId,
                                 String outTradeNo,
                                 String payTrace,
                                 String payTime){

        StringBuilder signStr = new StringBuilder();

        LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();

        Date date = new Date();

        map.put("pay_ver","100");
        map.put("pay_type","000");
        map.put("service_id","020");
        map.put("merchant_no",merchantNo);
        map.put("terminal_id",terminalId);
        map.put("terminal_trace","YunPengQuery"+System.currentTimeMillis());
        map.put("terminal_time",dateTimeFormat.format(date));
        map.put("out_trade_no",outTradeNo);


        for(Map.Entry<String, String> entry : map.entrySet()) {
            signStr.append(entry.getKey() + "=" + entry.getValue() + "&");
        }

        signStr.append("access_token=").append(TOKEN);
        System.out.println(signStr);
        String keySign = MD5Util.MD5Lower32(signStr.toString());
        map.put("key_sign",keySign);
        if (!StringUtils.isEmpty(payTrace)){
            map.put("pay_trace",payTrace);
            map.put("pay_time",payTime);
        }

        String jsonString = JSON.toJSONString(map);
        return getPostRessultJson("/pay/100/query",jsonString);
    }


    /**
     * @Author: yujing
     * @Description: 扫呗退款
     * @param merchantNo 商户号
	 * @param terminalId 终端号
	 * @param outTradeNo qrcodePay获取的得到的outTradeNo
	 * @param refundFee 退款金额，单位分
     * @DateTime: 2020/6/9 17:41
     * @Return void
     */
    public void refundOrder(String merchantNo,
                            String terminalId,
                            String outTradeNo,
                            String refundFee){

        StringBuilder signStr = new StringBuilder();

        LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();

        Date date = new Date();

        map.put("pay_ver","100");
        map.put("pay_type","000");
        map.put("service_id","030");
        map.put("merchant_no",merchantNo);
        map.put("terminal_id",terminalId);
        map.put("terminal_trace","YunPengRefund"+System.currentTimeMillis());
        map.put("terminal_time",dateTimeFormat.format(date));
        map.put("refund_fee",refundFee);
        map.put("out_trade_no",outTradeNo);

        for(Map.Entry<String, String> entry : map.entrySet()) {
            signStr.append(entry.getKey() + "=" + entry.getValue() + "&");
        }

        signStr.append("access_token=").append(TOKEN);
        System.out.println(signStr);
        String keySign = MD5Util.MD5Lower32(signStr.toString());
        map.put("key_sign",keySign);

        String jsonString = JSON.toJSONString(map);
        getPostRessultJson("/pay/100/refund",jsonString);
    }


    /**
     * @Author: yujing
     * @Description: 撤销订单
     * @param merchantNo 
	 * @param terminalId
	 * @param outTradeNo
	 * @param payTrace
	 * @param payTime
     * @DateTime: 2020/6/9 17:42
     * @Return void
     */
    public void cancelOrder(String merchantNo,
                            String terminalId,
                            String outTradeNo,
                            String payTrace,
                            String payTime){

        StringBuilder signStr = new StringBuilder();

        LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();

        Date date = new Date();

        map.put("pay_ver","100");
        map.put("pay_type","000");
        map.put("service_id","040");
        map.put("merchant_no",merchantNo);
        map.put("terminal_id",terminalId);
        map.put("terminal_trace",System.currentTimeMillis()+"");
        map.put("terminal_time",dateTimeFormat.format(date));

        for(Map.Entry<String, String> entry : map.entrySet()) {
            signStr.append(entry.getKey() + "=" + entry.getValue() + "&");
        }

        signStr.append("access_token=").append(TOKEN);
        System.out.println(signStr);
        String keySign = MD5Util.MD5Lower32(signStr.toString());
        map.put("key_sign",keySign);
        if(StringUtils.hasText(outTradeNo)) {
            map.put("out_trade_no", outTradeNo);
        }else {
            map.put("pay_trace",payTrace);
            map.put("pay_time",payTime);
        }

        String jsonString = JSON.toJSONString(map);
        getPostRessultJson("/pay/100/cancel",jsonString);
    }



    private JSONObject getPostRessultJson(String apiUrl,
                                          String httpParam){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        logger.info("扫呗接口"+apiUrl+"发送Param:  " + httpParam);
        HttpEntity<String> entity = new HttpEntity<String>(httpParam, headers);
        ResponseEntity<String> resp = restTemplate.postForEntity(URL+apiUrl, entity, String.class);
        String result = resp.getBody();
        logger.info("扫呗Result:  " + result);
        JSONObject json = JSONObject.parseObject(result);
        return json;
    }
}
